package mylab.starters.uuid.impl.mysql;

import mylab.starters.uuid.AbstractUuidTemplate;
import mylab.starters.uuid.Uuid;
import mylab.starters.uuid.UuidProvider;
import mylab.starters.uuid.config.UuidProperties;
import mylab.starters.uuid.model.BusinessName;
import mylab.starters.uuid.model.Prefix;
import mylab.starters.uuid.model.impl.DatabaseRangeManager;
import mylab.starters.uuid.model.impl.DefaultBusinessName;
import mylab.starters.uuid.model.impl.DefaultPrefix;
import mylab.starters.uuid.model.impl.DefaultRangeId;
import mylab.utils.spring.spi.SpiProvider;

import javax.sql.DataSource;

/**
 * <p>
 * 基于Database取步长，主键生成器工厂类
 * </p>
 */

public class MysqlUuidTemplate extends AbstractUuidTemplate<UuidProperties.MysqlUuidProperties> {
    /**
     * 数据库数据源[必选]
     */
    private DataSource dataSource;
    /**
     * 业务名称[必选]
     */
    private BusinessName businessName;
    /**
     * 主键前缀[可选：默认为空]
     */
    private Prefix prefix = new DefaultPrefix();

    /**
     * 存放序列号步长的表[可选：默认：sequence]
     */
    private String tableName;
    /**
     * 并发是数据使用了乐观策略，这个是失败重试的次数[可选：默认：100]
     */
    private int retryTimes = 100;
    /**
     * 获取range步长[可选：默认：1000]
     */
    private int step = 1000;

    /**
     * 序列号分配起始值[可选：默认：0]
     */
    private long stepStart = 0;

    public MysqlUuidTemplate() {

    }

    public MysqlUuidTemplate(UuidProperties.MysqlUuidProperties properties) {
        super(properties);
        this.businessName = new DefaultBusinessName(properties.getBusinessName());
        this.prefix = new DefaultPrefix(properties.getPrefix());
        this.tableName = properties.getTableName();
        this.retryTimes = properties.getRetryTimes();
        this.step = properties.getStep();
        this.stepStart = properties.getStepStart();
    }

    public static MysqlUuidTemplate create() {
        return new MysqlUuidTemplate();
    }

    public MysqlUuidTemplate dataSource(DataSource dataSource) {
        this.dataSource = dataSource;
        return this;
    }

    public MysqlUuidTemplate tableName(String tableName) {
        this.tableName = tableName;
        return this;
    }

    public MysqlUuidTemplate retryTimes(int retryTimes) {
        this.retryTimes = retryTimes;
        return this;
    }

    public MysqlUuidTemplate step(int step) {
        this.step = step;
        return this;
    }

    public MysqlUuidTemplate businessName(BusinessName businessName) {
        this.businessName = businessName;
        return this;
    }

    public MysqlUuidTemplate prefix(Prefix prefix) {
        this.prefix = prefix;
        return this;
    }

    public MysqlUuidTemplate stepStart(long stepStart) {
        this.stepStart = stepStart;
        return this;
    }

    @Override
    public Uuid getInstance() {
        //利用DB获取区间管理器
        DatabaseRangeManager databaseRangeManager = new DatabaseRangeManager();
        databaseRangeManager.setDataSource(this.dataSource);
        databaseRangeManager.setTableName(this.tableName);
        databaseRangeManager.setRetryTimes(this.retryTimes);
        databaseRangeManager.setStep(this.step);
        databaseRangeManager.setStepStart(stepStart);
        databaseRangeManager.init();
        //构建序列号生成器
        DefaultRangeId defaultRangeId = new DefaultRangeId();
        defaultRangeId.setBusinessName(this.businessName);
        defaultRangeId.setPrefix(this.prefix);
        defaultRangeId.setRangeManager(databaseRangeManager);
        return defaultRangeId;
    }

    @Override
    public SpiProvider getProvider() {
        return UuidProvider.Mysql;
    }
}
